const got = require('got');
const headers = require('./getHeaders')();
const { getProxy,
  writeToRedisData,
  getToRedisData,
  deleteToRedisData } = require('./redis');
const HttpsProxyAgent = require('https-proxy-agent');
const faker = require('faker');
const util = require('util');
const sleep = util.promisify(setTimeout);

/**
 * 代理请求
 * @param {请求地址} url 
 * @returns 
 */
async function makeRequest(url) {
  let retryCount = 0;
  let cookie = await loadCookie();
  while (retryCount < 3) {
    const proxyUrl = await getProxy();
    let headers_opt = {
      ...headers,
      'User-Agent': await getToRedisData('user_agent') || faker.internet.userAgent(),
    };
    if (cookie) {
      headers_opt['Cookie'] = cookie;
    }
    const options = {
      method: 'GET',
      headers: headers_opt,
      agent: { https: new HttpsProxyAgent.HttpsProxyAgent(proxyUrl) },
      timeout: {
        lookup: 100,
        connect: 1000,
        secureConnect: 1000,
        socket: 1000,
        send: 10000,
        response: 1000
      }
    };
    try {
      const response = await got(url, options);
      if (response.statusCode == 403) {
        // 清空cookie
        await deleteToRedisData('cookie_key');
        await deleteToRedisData('user_agent');
      }
      if (response.statusCode !== 200) {
        retryCount++;
        console.error(`Request failed ${retryCount} times with status code ${response.statusCode}`);
        await sleep(getRandomInt(200, 800));
        if (retryCount === 3) {
          return response.body;
        }
        continue; // 继续重试
      }
      console.log(`Request success ${url} ${retryCount} times with status code ${response.statusCode}`);
      const setCookieHeader = response.headers['set-cookie'];
      if (setCookieHeader && setCookieHeader.length > 0 && (cookie == '' || cookie == null || cookie == undefined)) {
        //保存cookie
        const firstPartsOfCookies = setCookieHeader
          .map(cookieString => cookieString.split(';')[0])
          .filter(str => str.startsWith('ll=') || str.startsWith('bid='))
          .filter(str => str !== ''); // 过滤掉空字符串
        console.log('firstPartsOfCookies', firstPartsOfCookies);
        if (firstPartsOfCookies.length > 0) {
          const parsedCookies = JSON.stringify(firstPartsOfCookies);
          // const parsedCookies = cookieParser.JSONCookies(setCookieHeader);
          console.log(headers_opt['User-Agent']);
          console.log('parsedCookies', parsedCookies);
          // 一小时
          await writeToRedisData('cookie_key', parsedCookies, 60 * 60 * 1);
          // 5分钟
          await writeToRedisData('user_agent', headers_opt['User-Agent'], 300);
          cookie = await loadCookie();
          console.log('request success cookie:', cookie);
        }
      }
      return response.body;
    } catch (error) {
      console.error(`${retryCount} retry times Error making request:${url}`, error);
      retryCount++;
      await sleep(getRandomInt(200, 800));
      if (retryCount === 3) {
        console.error(`Max retries exceeded.${retryCount}`);
        throw error;
      }
    }
  }
  throw new Error('Max retries exceeded.');
}

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

async function loadCookie() {
  try {
    const data = await getToRedisData('cookie_key');
    if (data) {
      console.log('redis cookie key :', data);
      return Object.entries(JSON.parse(data)).map(([, value]) => `${value}`).join('; ');
    }
  } catch (error) {
    return '';
  }
}
module.exports = {
  makeRequest
};